package com.ruoyi.project.ins.controller;

import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.ins.api.InsApi;
import com.ruoyi.project.ins.domain.*;
import com.ruoyi.project.ins.service.IInsAccountService;
import com.ruoyi.project.ins.service.IInsBatchMessageService;
import com.ruoyi.project.ins.service.IInsMessageService;
import com.ruoyi.project.ins.service.IInsWebProxyService;
import com.ruoyi.project.system.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@RestController
@RequestMapping("/ins/account")
@Slf4j
public class InsAccountController extends BaseController {
    @Autowired
    private IInsAccountService insAccountService;

    @Autowired
    private IInsMessageService insMessageService;

    @Autowired
    private IInsBatchMessageService insBatchMessageService;

    @Autowired
    private IInsWebProxyService insWebProxyService;

    @Autowired
    private ISysConfigService configService;

    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response)
    {
        ExcelUtil<InsAccount> util = new ExcelUtil<>(InsAccount.class);
        util.importTemplateExcel(response, "账号数据");
    }

    @PreAuthorize("@ss.hasPermi('ins:account:list')")
    @GetMapping("/list")
    public TableDataInfo list(InsAccount insAccount)
    {
        String username = getUsername();
        if (!username.equalsIgnoreCase("admin")) {
            insAccount.setCreateBy(username);
        }
        startPage();
        List<InsAccount> list = insAccountService.selectAccountList(insAccount);
        return getDataTable(list);
    }

    @PreAuthorize("@ss.hasPermi('ins:account:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable Long id)
    {
        return success(insAccountService.selectAccountById(id));
    }

    @Log(title = "ins账号管理", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('ins:account:export')")
    @PostMapping("/export")
    public void export(HttpServletResponse response, InsAccount insAccount)
    {
        String username = getUsername();
        if (!username.equalsIgnoreCase("admin")) {
            insAccount.setCreateBy(username);
        }
        List<InsAccount> list = insAccountService.selectAccountList(insAccount);
        ExcelUtil<InsAccount> util = new ExcelUtil<>(InsAccount.class);
        util.exportExcel(response, list, "账号数据");
    }

    @Log(title = "ins账号管理", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('ins:account:import')")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
    {
        ExcelUtil<InsAccount> util = new ExcelUtil<>(InsAccount.class);
        List<InsAccount> registerList = util.importExcel(file.getInputStream());
        String operateName = getUsername();
        String message = insAccountService.importAccount(registerList, operateName);
        return success(message);
    }

    @PreAuthorize("@ss.hasPermi('ins:account:add')")
    @Log(title = "ins账号管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody InsAccount insAccount)
    {
        InsAccount ins = insAccountService.selectByUserId(insAccount.getUserId());
        if (ObjectUtils.isNotEmpty(ins)) {
            return error("该用户id已存在：" + insAccount.getUserId());
        }
        insAccount.setCreateBy(getUsername());
        insAccount.setSourceType("2");
        insAccount.setStatus("0");
        insAccount.setSendTimes(0);
        return toAjax(insAccountService.insertInsAccount(insAccount));
    }

    @PreAuthorize("@ss.hasPermi('ins:account:edit')")
    @Log(title = "ins账号管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody InsAccount insAccount)
    {
        InsAccount ins = insAccountService.selectByUserId(insAccount.getUserId());
        // 当库里存在新userId，且id记录与修改目标的id不一样，说明修改的新userId数据库已存在
        if (ObjectUtils.isNotEmpty(ins) && !Objects.equals(ins.getId(), insAccount.getId())) {
            return error("该用户id已存在：" + insAccount.getUserId());
        }
        insAccount.setUpdateBy(getUsername());
        return toAjax(insAccountService.updateInsAccount(insAccount));
    }

    @PreAuthorize("@ss.hasPermi('ins:account:remove')")
    @Log(title = "ins账号管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{deleteIds}")
    public AjaxResult remove(@PathVariable Long[] deleteIds)
    {
        return toAjax(insAccountService.deleteByIds(deleteIds));
    }

    @Log(title = "ins账号管理-单发消息", businessType = BusinessType.OTHER)
    @PreAuthorize("@ss.hasPermi('ins:account:singleMessage')")
    @PostMapping("/send/singleMessage")
    public AjaxResult sendSingleMessage(@RequestBody InsMessage insMessage) {
        String createUser = getUsername();
        InsWebProxy insWebProxy = insWebProxyService.selectValidWebProxyBySysUser(createUser);
        if (insWebProxy == null) {
            return error("操作失败，请先为当前账号配置网络代理");
        }
        insMessage.setStatus("0");
        insMessage.setFailTimes(0);
        insMessage.setCreateBy(createUser);
        insMessage.setSendType("0");
        insMessage.setProxyServer(insWebProxy.getProxyServer());
        insMessage.setProxyPort(insWebProxy.getProxyPort());
        insMessage.setProxyCustomer(insWebProxy.getProxyCustomer());
        insMessage.setProxyPassword(insWebProxy.getProxyPassword());
        int row = insMessageService.insertInsMessage(insMessage);
        if (row <= 0) {
            return error("操作失败，插入消息失败");
        }
        return toAjax(insAccountService.updateSendTimesByUserId(insMessage.getSendUserid()));
    }

    @Log(title = "ins账号管理-批量发消息", businessType = BusinessType.OTHER)
    @PreAuthorize("@ss.hasPermi('ins:account:batchMessage')")
    @PostMapping("/send/batchMessage")
    public AjaxResult sendBatchMessage(@RequestBody InsBatchMessage batchMessage) {
        String username = getUsername();
        InsWebProxy insWebProxy = insWebProxyService.selectValidWebProxyBySysUser(username);
        if (insWebProxy == null) {
            return error("操作失败，请先为当前账号配置网络代理");
        }
        Integer sendTimes = batchMessage.getSendTimes();
        if (sendTimes == null || sendTimes <= 0 || sendTimes > 10) {
            return error("批量发送消息失败，发送消息次数必须是1~10的整数");
        }
        InsAccount insAccount = batchMessage.getQueryParams();
        if (!username.equalsIgnoreCase("admin")) {
            insAccount.setCreateBy(username);
        }
        List<InsAccount> accountList = insAccountService.selectAccountList(insAccount);
        if (CollectionUtils.isEmpty(accountList)) {
            return error("批量发送消息失败，未找到有效的发送账号");
        }
        List<InsAccount> targetAccountList = (batchMessage.getStartIndex() != null && batchMessage.getEndIndex() != null)
                ? accountList.subList(batchMessage.getStartIndex() - 1, Math.min(batchMessage.getEndIndex(), accountList.size()))
                : accountList;
        batchMessage.setCreateBy(username);
        return insBatchMessageService.sendBatchMessage(batchMessage, targetAccountList, insWebProxy);
    }

    @PreAuthorize("@ss.hasPermi('ins:account:checkAlive')")
    @PostMapping("/checkAlive")
    public AjaxResult checkAlive(@RequestBody InsAccount insAccount) {
        InsWebProxy proxy = insWebProxyService.selectValidWebProxyBySysUser(getUsername());
        if (proxy == null) {
            return error("操作失败，请先为当前账号配置网络代理");
        }
        if (StringUtils.isBlank(insAccount.getUsername())) {
            return AjaxResult.error("账号名称为空，无法检测是否存活");
        }
        if (insAccount.getStatus().equals("1")) {
            return AjaxResult.error("账号已经废弃，无需再进行检测");
        }
        log.info("收到检测账号任务: {}", insAccount);
        InstagramAccount account = InstagramAccount.builder()
            .username(insAccount.getUsername()).userId(insAccount.getUserId()).bearerToken(insAccount.getAuth())
            .rur(insAccount.getRur()).wwwClaim(insAccount.getClaim()).mid(insAccount.getMid())
            .build();
        proxy.setCountryCode(insAccount.getCountryCode());
        Boolean accountAlive = InsApi.checkAccountAlive(account, proxy);
        if (accountAlive == null) {
            log.info("获取账号状态失败");
            insAccount.setCheckResult("未知状态");
            insAccount.setCheckTime(new Date());
            insAccountService.updateInsAccount(insAccount);
            return AjaxResult.error("获取账号状态失败");
        }
        if (accountAlive) {
            insAccount.setStatus("0");
            insAccount.setCheckResult("账号存活");
            insAccount.setCheckTime(new Date());
            insAccountService.updateInsAccount(insAccount);
            log.info("检测成功，账号仍存活");
            return AjaxResult.success("检测成功，账号仍存活");
        } else {
            insAccount.setStatus("1");
            insAccount.setCheckResult("账号被封");
            insAccount.setCheckTime(new Date());
            insAccountService.updateInsAccount(insAccount);
            log.info("检测成功，账号被封");
            return AjaxResult.warn("检测成功，账号被封");
        }
    }
}
